<?php
/**
 * 學生亂數編班
 * @author cik
 *
 */
class StudentPlace_RandController extends Zend_Controller_Action
{

    public function indexAction()
    {
    }

    /**
     * 檢查檔案是否存在
     * @return unknown_type
     */
    public function checkFileAction()
    {
        $fileName = $this->_getParam('selectYearSemester').'-'.$this->_getParam('selectGrade');

        $q = Doctrine_Query::create()
        ->select('sn')
        ->from('Student_Model_StudentSemesterRand')
        ->where('source_year_semester=?',$fileName);

        $res = $q->fetchOne();

        if ($res)
        $this->_helper->json(true);
        else
        $this->_helper->json(false);
    }

    /**
     * 檢查有否學生設定
     * @return unknown_type
     */
    public function checkStudentsAction()
    {
        $yearSemester = $this->_getParam('yearSemester');

        $q = Doctrine_Query::create()
        ->select('is_over')
        ->from('Student_Model_StudentSemesterRand')
        ->where('year_semester=?', $yearSemester)
        ->fetchOne();

        if ($q->is_over)
        $this->_helper->json(true);
        else
        $this->_helper->json(false);
    }

    /**
     * 刪除編班設定
     * @return unknown_type
     */
    public function deleteSemesterAction()
    {
        $yearSemester = $this->_getParam('yearSemester');

        $res =  Doctrine_Query::create()
        ->delete('Student_Model_StudentSemesterRand')
        ->where('year_semester=?', $yearSemester)
        ->execute();

        $this->_helper->json($res);
    }


    /**
     * 學期資料
     * @return unknown_type
     */
    public function getSemesterData()
    {
        $res = Doctrine_Query::create()
        ->select('sn, year_semester, classes, new_class_num, is_over')
        ->from('Student_Model_StudentSemesterRand')
        ->orderBy('year_semester DESC')
        ->fetchArray();

        return $res;
    }

    /**
     * 第一步
     * @return unknown_type
     */
    public function step1Action()
    {
        // 儲存學期編班記錄
        if ($this->_getParam('save') == 1) {

            $arr = $this->getRequest()->getParams();

            $res = array();
            $tempArr = array();

            foreach ($arr['selectClassSn'] as $val)
            $tempArr[] =  end(explode('-',$val));

            $res['classes'] = implode(',',$tempArr);
            $res['new_class_num'] = $arr['totalClass'];
            $res['source_year_semester'] = $arr['selectYearSemester'].'-'.$arr['selectGrade'];
            // 加上目前的學期
            $tempArr = explode('-', $arr['selectYearSemester']);

            if ($tempArr[1] == 1)
            $res['year_semester'] = $tempArr[0].'-2-'. $arr['selectGrade'];
            else
            $res['year_semester'] = ($tempArr[0]+1).'-1-'. ($arr['selectGrade']+1);

            $student_semester_rand  = new Student_Model_StudentSemesterRand();

            $res['is_over'] = Student_Model_StudentSemesterRandGroup::EMPTY_STEP;

            $student_semester_rand->fromArray($res);

            $student_semester_rand->save();
        }

        $this->view->yearSemester = $this->_getParam('selectYearSemester');

        $this->view->grade = $this->_getParam('selectGrade');
        // 已存在的編班資料
        $this->view->semesterList = $this->getSemesterData();

        // 班級
        if ($this->_getParam('selectYearSemester') ){

            $semester = new Semester_Model_SemesterClass();

            $arr = explode("-", $this->_getParam('selectYearSemester'));
            // 班名
            $this->view->className = $semester->getGradeClassNames($arr[0],$arr[1],$this->view->grade);
        }
    }


    /**
     * 第二步
     * @return unknown_type
     */
    public function step2Action()
    {
        $studentGroup = new Student_Model_StudentSemesterRandGroup();

        $form = new StudentPlace_Form_StudentSemesterRandGroup();

        if ($this->getRequest()->isPost()) {

            if ($form->isValid($this->_getAllParams())) {
                if ($form->getValue('group_sn'))
                $studentGroup->assignIdentifier($form->getValue('group_sn'));
                $studentGroup->fromArray($form->getValues());
                $studentGroup->save();

                $this->_redirect('studentPlace/rand/step2');
            }
        }

        $this->view->form = $form;

        $this->view->allData = $studentGroup->getTable()->findAll();
    }

    /**
     * 第三步
     * @return unknown_type
     */
    public function step3Action()
    {
        $this->view->yearSemester = $this->_getParam('selectYearSemester');

        $this->view->grade = $this->_getParam('selectGrade');
        // 已存在的編班資料
        $this->view->semesterList = $this->getSemesterData();

    }

    /**
     *  第四步
     * @return unknown_type
     */
    public function step4Action()
    {
        $this->view->yearSemester = $this->_getParam('selectYearSemester');

        $this->view->grade = $this->_getParam('selectGrade');
        // 已存在的編班資料
        $this->view->semesterList = $this->getSemesterData();
    }

    public function step5Action()
    {

    }
    /**
     *  取得編班資料
     * @return unknown_type
     */
    public function getRandRunAction()
    {
        $this->getHelper('layout')->disableLayout();

        $sn = (int)$this->_getParam('id');

        $res = Doctrine_Query::create()
        ->from('Student_Model_StudentSemesterRand')
        ->where('sn=?', $sn)
        ->fetchOne();

        $this->view->data = $res;
    }

    /**
     * 進行編班作業
     * 1. 先編群組學生
     * 2. 如有抽換學生時,記住抽換班級人數
     * 3. 算出各班平均人數
     * 4.將陣列打亂,按序編排
     * 5.餘數部份再依序填進
     *
     */
    public function randRunAction()
    {
        $newClassNum = (int)$this->_getPAram('new_class_num');

        if ($newClassNum==0)
        throw new Exception("class numbers can't  equal zero");

        $sn = (int)$this->_getParam('sn') ;

        // 更新編班班級數
        Doctrine_Query::create()
        ->update('Student_Model_StudentSemesterRand')
        ->set('new_class_num','?',$newClassNum)
        ->set('is_over','?', Student_Model_StudentSemesterRandGroup::FINISHED)
        ->where('sn=?', $sn)
        ->execute();

        // 取出所有的學生
        $res = Doctrine_Query::create()
        ->from('Student_Model_StudentSemesterRandStudent')
        ->where('semester_sn=?', $sn)
        ->andWhere('is_join>?', 0)
        ->fetchArray();

        $studentArr = array();
        // 學生總數
        $totalNumber = array();

        foreach($res as $row) {
            $studentArr[$row['student_type']][] = $row;
            $totalNumber[$row['student_sex']] ++;
        }
        // 先編排群組學生
        $res = Doctrine_Query::create()
        ->from('Student_Model_StudentSemesterRandGroup')
        ->fetchArray();

        // 開始編排班級
        $currClass = rand(1, $newClassNum);
        // 目前編排人數
        $classAssignNumber = array();
        // 編排結果
        $resultArr = array();
        // 群組學生
        $groupNumber = array();

        //群組打亂
        $this->shuffle_assoc($res);

        foreach ($res as $row) {

            $tempStudentArr = $studentArr[$row['group_sn']];

            if ($tempStudentArr) {

                foreach ($tempStudentArr as $val) {
                    $i  = $currClass % ($newClassNum)+1;
                    $resultArr[$i][$val['student_sex']][] = $val;
                    $classAssignNumber[$i][$val['student_sex']]++;
                    $classAssignNumber[$i]['total'][$val['student_sex']] += 1+ $row['student_numbers'];
                    $groupNumber[$val['student_sex']] += $row['student_numbers'];

                    if ($row['is_exclusive'] == 0) // 不編在同一班
                    $currClass++;
                }

            }
        }
        // 打亂陣列
        $this->shuffle_assoc($studentArr[0]);

        // 編排一般生
        foreach ($studentArr[0] as $row)
        $tempStudentArr[$row['student_sex']][] = $row;

        // 男生平均數
        $averageNumber_M =  (int) (($totalNumber['M'] + $groupNumber['M']) / $newClassNum);
        // 男生餘數
        $lastNums_M =  ($totalNumber['M'] + $groupNumber['M']) - $averageNumber_M * $newClassNum;



        // 女生平均數
        $averageNumber_F =  (int) (($totalNumber['F'] + $groupNumber['F']) / $newClassNum);
        // 女生餘數
        $lastNums_F = ($totalNumber['F'] + $groupNumber['F']) - $averageNumber_F * $newClassNum;

        $tempi = 0;
        for($i=1; $i<= $newClassNum ; $i++) {

            $num = $averageNumber_M - $classAssignNumber[$i]['total']['M'];

            for ($j=$tempi  ; $j< ($num+$tempi)  ;$j++ )
            $resultArr[$i]['M'][] = $tempStudentArr['M'][$j];

            $tempi += $num;
        }

        // 男生人數補齊
        $si  = $currClass % ($newClassNum);

        for($i = $si ; $i< ($lastNums_M +$si) ;$i++) {

            $ti  = $currClass % ($newClassNum)+1;

            $resultArr[$ti]['M'][] = $tempStudentArr['M'][$tempi];

            $tempi++;

            $currClass++;
        }

        $tempi = 0;

        for($i=1; $i<= $newClassNum ; $i++) {

            $num = $averageNumber_F - $classAssignNumber[$i]['total']['F'];

            for ($j=$tempi  ; $j< ($num+$tempi)  ;$j++ ) {
                $resultArr[$i]['F'][] = $tempStudentArr['F'][$j];
            }

            $tempi += $num;
        }

        // 女生人數補齊
        $si  = $currClass % ($newClassNum);

        for($i = $si ; $i< ($lastNums_F +$si) ;$i++) {
            $ti  = $currClass % ($newClassNum)+1;
            $resultArr[$ti]['F'][] = $tempStudentArr['F'][$tempi];
            $tempi++;
            $currClass++;
        }

        foreach ($resultArr as $id=>$row) {

            $number = 1;

            foreach ($row['M']  as $val) {
                Doctrine_Query::create()
                ->update('Student_Model_StudentSemesterRandStudent')
                ->set('new_class','?', $id)
                ->set('new_number','?', $number++)
                ->where('sn=?', $val['sn'])
                ->execute();

            }

            foreach ($row['F']  as $val) {
                Doctrine_Query::create()
                ->update('Student_Model_StudentSemesterRandStudent')
                ->set('new_class','?', $id)
                ->set('new_number','?', $number++)
                ->where('sn=?', $val['sn'])
                ->execute();

            }
        }
        $this->_redirect('studentPlace/rand/step4');
    }


    /**
     *  陣列亂數排序
     * @param $array
     */
    function shuffle_assoc(&$array) {
        $keys = array_keys($array);

        shuffle($keys);

        foreach($keys as $key) {
            $new[$key] = $array[$key];
        }

        $array = $new;

        return true;
    }

    /**
     * 產生學生名冊
     * @return unknown_type
     */
    public function generateStudentAction()
    {
        $sn = (int)$this->_getParam('sn') ;

        $q = Doctrine_Query::create()
        ->from('Student_Model_StudentSemesterRand')
        ->where('sn=?',$sn);
        $res = $q->fetchOne();
        $res->is_over = Student_Model_StudentSemesterRandGroup::HAS_STUDENT;
        $res->save();

        $semesterSn = $res->sn;

        $tempArr = explode("-", $res->source_year_semester);
        $year = $tempArr[0];
        $semester = $tempArr[1];
        $grade = $tempArr[2];

        // 取出班名
        $semesterClass = new Semester_Model_SemesterClass();

        $className = $semesterClass->getClassNames($tempArr[0], $tempArr[1], $tempArr[2]);


        $q = Doctrine_Query::create()
        ->select('a.sn, a.student_id, a.name, a.sex, a.study_condition,b.class_sn AS class_sn, b.number AS number ')
        ->from('Student_Model_Student a')
        ->leftJoin('a.Student_Model_StudentSemester b')
        ->where('b.year=?', $year)
        ->andWhere('b.semester=?', $semester)
        ->andWhere('b.grade=?',$grade)
        ->andWhereIn('a.study_condition', array(Student_Model_StudentTransfer::IN_STADY,
        Student_Model_StudentTransfer::HOMESCHOOLING))
        ->orderBy('b.class_sn, b.number');


        foreach ($q->fetchArray() as $val) {
            $arr = array();
            $arr['semester_sn'] = $semesterSn;
            $arr['student_sn'] = $val['sn'];
            $arr['student_id'] = $val['student_id'];
            $arr['student_name'] = $val['name'];
            $arr['number'] = $val['number'];
            $arr['student_sex'] = $val['sex'];
            $arr['class_sn'] = $val['class_sn'];
            $arr['class_name'] = $className[$val['class_sn']];
            $randStudent = new Student_Model_StudentSemesterRandStudent();
            $randStudent->fromArray($arr);
            $randStudent->save();
        }

        $this->_helper->json(true);
    }

    /**
     * 刪除學生名冊
     * @return unknown_type
     */
    public function deleteStudentAction()
    {
        $sn = (int) $this->_getParam('sn') ;

        // 先將 master table is_over 設為未結束
        Doctrine_Query::create()
        ->update('Student_Model_StudentSemesterRand')
        ->set('is_over','?', Student_Model_StudentSemesterRandGroup::EMPTY_STEP)
        ->where('sn=?', $sn)
        ->execute();

        // 刪除學生記錄
        $q = Doctrine_Query::create()
        ->delete('Student_Model_StudentSemesterRandStudent')
        ->where('semester_sn=?', $sn);

        $this->_helper->json($q->execute());
    }

    public function getClassListAction()
    {
        $this->getHelper('layout')->disableLayout();

        $sn = (int) $this->_getParam('sn');

        $q = Doctrine_Query::create()
        ->from ('Student_Model_StudentSemesterRand')
        ->where('sn=?', $sn);
        $res = $q->fetchOne();

        $tempArr = explode("-", $res->source_year_semester);
        // 取出班名
        $semesterClass = new Semester_Model_SemesterClass();

        $className = $semesterClass->getClassNames($tempArr[0], $tempArr[1], $tempArr[2]);

        $arr = array();

        foreach (explode(",", $res->classes) as $id)
        $arr[$id] = $className[$id];

        $this->view->semesterSn = $sn;

        $this->view->className = $arr;

    }

    /**
     * 取出班級學生
     * @return unknown_type
     */
    public function getStudentsAction()
    {
        $this->getHelper('layout')->disableLayout();

        $classSn = (int)$this->_getParam('class_sn');

        $semesterSn = (int) $this->_getPAram('semesterSn');

        $res = Doctrine_Query::create()
        ->from('Student_Model_StudentSemesterRandStudent')
        ->where('semester_sn=?', $semesterSn)
        ->andwhere('class_sn=?', $classSn)
        ->orderBy('number')
        ->fetchArray();

        $this->view->data = $res;

        $this->view->semesterSn = $semesterSn;

        $this->view->joinArr = array('1'=>'join','0'=>'unJoin');
        // 群組
        $res = Doctrine_Query::create()
        ->from('Student_Model_StudentSemesterRandGroup')
        ->fetchArray();
        $arr = array();

        foreach ($res as $row)
        $arr[$row['group_sn']] = $row['group_name'];

        $this->view->typeArr = $arr;

    }


    /**
     *  儲存學生類別
     */
    public function saveStudentKindAction()
    {
        $semesterSn = $this->_getParam('semester_sn');

        $studentKindArr =  $this->_getParam('student_type');

        $isJoinArr =  $this->_getParam('is_join');

        foreach ($studentKindArr as $sn=>$val) {

            $q = Doctrine_Query::create()
            ->update('Student_Model_StudentSemesterRandStudent')
            ->set('student_type','?', (int) $val)
            ->set('is_join','?', (int) $isJoinArr[$sn])
            ->where('semester_sn=?', $semesterSn)
            ->andWHere('sn=?', $sn);
            $q->execute();

        }
        $this->_helper->json(true) ;
    }

    /**
     * 刪除群組資料
     */
    public function deleteGroupAction()
    {
        $sn = (int)$this->_getParam('sn');

        $res = Doctrine_Query::create()
        ->delete('Student_Model_StudentSemesterRandGroup')
        ->where('group_sn=?', $sn)
        ->execute();

        $this->_helper->json($res);
    }

    /**
     * 取群組資料
     */
    public function getGroupDataAction()
    {
        $sn = (int) $this->_getParam('sn');

        $res = Doctrine_Query::create()
        ->from('Student_Model_StudentSemesterRandGroup')
        ->where('group_sn=?', $sn)
        ->fetchOne(null, Doctrine_Core::HYDRATE_ARRAY);

        $this->_helper->json($res);
    }


    public function resetGroupStateAction()
    {
        $sn = (int) $this->_getParam('sn');

        Doctrine_Query::create()
        ->update('Student_Model_StudentSemesterRand')
        ->set('is_over','?', Student_Model_StudentSemesterRandGroup::HAS_STUDENT)
        ->where('sn=?', $sn)
        ->execute();
        $this->_helper->json($sn);
    }

    /**
     * 取出編班結果
     */
    public function getResultAction()
    {
        $this->getHelper('layout')->disableLayout();

        $sn = (int) $this->_getParam('sn');

        //        $year_semester = Doctrine_Query::create()
        //        ->select('source_year_semester')
        //        ->from ('Student_Model_StudentSemesterRand')
        //        ->where('sn=?', $sn)
        //        ->fetchOne()->source_year_semester;
        //
        //        $tempArr = explode('-', $year_semester);
        //        // 取出班名
        //        $semesterClass = new Semester_Model_SemesterClass();
        //        $className = $semesterClass->getClassNames($tempArr[0], $tempArr[1], $tempArr[2]);
        //
        //        $arr = array();
        //
        //        foreach ($className as $id=>$name)
        //        $arr[$id] = $name;
        //        $this->view->className = $arr;

        $res = Doctrine_Query::create()
        ->from ('Student_Model_StudentSemesterRandStudent')
        ->where('semester_sn=?', $sn)
        ->andWHere('is_join>?', 0)
        ->orderBy('new_class, new_number')
        ->fetchArray();

        $arr = $total = array();
        foreach($res as $row) {
            if (!isset($total['sex'][$row['new_class']][$row['student_sex']]))
            $total['sex'][$row['new_class']][$row['student_sex']] = 0;
            if (!isset($total['type'][$row['new_class']][$row['student_type']]))
            $total['type'][$row['new_class']][$row['student_type']] = 0;

            $arr[$row['new_class']][] = $row;
            $total['sex'][$row['new_class']][$row['student_sex']] ++;
            $total['type'][$row['new_class']][$row['student_type']] ++;
        }

        $this->view->data = $arr;
        $this->view->total = $total;

        // 群組名稱
        $res = Doctrine_Query::create()
        ->from('Student_Model_StudentSemesterRandGroup')
        ->fetchArray();
        $arr = array();

        foreach($res as $row)
        $arr[$row['group_sn']] = $row['group_name'];

        $this->view->groupName = $arr;

    }

    /**
     * 調整班序
     */
    public function getClassAdjustmentAction()
    {
        $this->getHelper('layout')->disableLayout();

        $sn = $this->_getParam('sn');

        $res = DOctrine_Query::create()
        ->from ('Student_Model_StudentSemesterRand')
        ->where('sn=?', $sn)
        ->fetchOne();
        if ($res)
        $this->view->data = $res->toArray();
    }

    /**
     * 更改班序
     */
    public function saveClassOrderAction()
    {
        $sn = (int) $this->_getParam('sn');
        $res = Doctrine_Query::create()
        ->select('sn, new_class')
        ->from('Student_Model_StudentSemesterRandStudent')
        ->where('semester_sn=?', $sn)
        ->andWhere('is_join >?', 0)
        ->fetchArray();
        $arr = array();
        foreach ($res as $row) {
            $arr[$row['new_class']][] = $row['sn'];
        }

        foreach ($this->_getParam('changeClass') as $class=>$newClass) {
            if ($class == $newClass)
            continue;
            //print_r($arr[$class]); exit;
            foreach($arr[$class] as $val) {
                Doctrine_Query::create()
                ->update('Student_Model_StudentSemesterRandStudent')
                ->set('new_class','?', $newClass)
                ->where('sn=?', $val)
                ->execute();
                // echo $newClass.'-'. $val.'<br>';
            }
        }
        //exit;
        $this->_redirect('studentPlace/rand/step4');
    }

    public function printResultAction()
    {
        $this->_helper->layout->setLayout('printStyle');
        $sn = (int) $this->_getParam('sn');

        $res = Doctrine_Query::create()
        ->select('a.* ,b.year_semester as year_semester')
        ->from ('Student_Model_StudentSemesterRandStudent a')
        ->leftJoin('a.Student_Model_StudentSemesterRand b')
        ->where('a.semester_sn=?', $sn)
        ->andWHere('a.is_join>?', 0)
        ->orderBy('a.new_class, a.new_number')
        ->fetchArray();

        $arr = $total = array();
        foreach($res as $row) {
            if (!isset( $total['sex'][$row['new_class']][$row['student_sex']]))
            $total['sex'][$row['new_class']][$row['student_sex']] = 0;
            if (!isset ($total['type'][$row['new_class']][$row['student_type']]))
            $total['type'][$row['new_class']][$row['student_type']] = 0;
            $arr[$row['new_class']][] = $row;
            $total['sex'][$row['new_class']][$row['student_sex']] ++;
            $total['type'][$row['new_class']][$row['student_type']] ++;
        }

        $this->view->data = $arr;
        $this->view->total = $total;

        // 群組名稱
        $res = Doctrine_Query::create()
        ->from('Student_Model_StudentSemesterRandGroup')
        ->fetchArray();
        $arr = array();

        foreach($res as $row)
        $arr[$row['group_sn']] = $row['group_name'];

        $this->view->groupName = $arr;

    }

}

